home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / ppl4c10.zip / XYMODEM.C < prev    next >
Text File  |  1995-02-09  |  10KB  |  336 lines

  1. /* xymodem.c */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <io.h>
  8. #include <sys\types.h>
  9. #include <sys\stat.h>
  10.  
  11. #include "pcl4c.h"
  12. #include "ascii.h"
  13. #include "term_io.h"
  14. #include "xypacket.h"
  15. #include "xymodem.h"
  16. #include "dir_io.h"
  17. #include "timing.h"
  18.  
  19. #define ABORT_CHAR CAN
  20.  
  21. #define FALSE 0
  22. #define TRUE !FALSE
  23.  
  24.  
  25. static int DataBits = WordLength8;
  26. static int StopBits = OneStopBit;
  27. static int Parity = NoParity;
  28.  
  29. static void Set8N1(int Port)
  30. {int  PSL;
  31.  PSL = SioRead(Port,3);
  32.  DataBits = 0x03 & PSL;
  33.  StopBits = 0x01 & (PSL>>2);
  34.  Parity = 0x07 & (PSL>>3);
  35.  /* set 8N1 */
  36.  SioParms(Port,NoParity,OneStopBit,WordLength8);
  37. }
  38.  
  39. static void RestorePSL(int Port)
  40. {/* restore old setting */
  41.  SioParms(Port,Parity,StopBits,DataBits);
  42. }
  43.  
  44. int TxyModem(
  45.    int Port,            /* COM port [0..3] */
  46.    char *Filename,      /* filename buffer */
  47.    char *Buffer,        /* data buffer */
  48.    int OneKflag,        /* if TRUE, use 1K blocks when possible */
  49.    int BatchFlag)       /* if TRUE, send filename in packet 0 */
  50. {int  i, k;
  51.  int  Code;
  52.  int  Handle;            /* file Handle */
  53.  long Tics;
  54.  char c;
  55.  int  p;
  56.  char PacketType;
  57.  char PacketNbr;
  58.  int  PacketSize = 128;
  59.  int  FirstPacket;
  60.  unsigned short CheckSum;
  61.  int Number1K = 0;       /* total # 1K packets */
  62.  int Number128 = 0;      /* total # 128 byte packets */
  63.  char NCGchar = NAK;
  64.  long FileSize;
  65.  char Temp[81];
  66.  int EmptyFlag = FALSE;
  67.  /* begin */
  68.  Set8N1(Port);
  69.  if(BatchFlag) if(Filename[0]=='\0') EmptyFlag = TRUE;
  70.  if(!EmptyFlag)
  71.      {/* Filename is not empty */
  72.       EmptyFlag = FALSE;
  73.       Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  74.       if(Handle<0)
  75.           {strcpy(Temp,"Cannot open ");
  76.            strcat(Temp,Filename);
  77.            WriteMsg(Temp);
  78.            RestorePSL(Port);
  79.            return(FALSE);
  80.           }
  81.      }
  82.  WriteMsg("XYMODEM send: waiting for Receiver ");
  83.  while(SioKeyPress()) SioKeyRead();
  84.  /* compute # blocks */
  85.  if(!EmptyFlag)
  86.      {FileSize = filelength(Handle);
  87.       if(OneKflag) Number1K = (int) (FileSize / 1024L);
  88.       Number128 = (int) ((FileSize-1024L*(long)Number1K) / 128L);
  89.       if(128L*Number128+1024*Number1K < FileSize) Number128++;
  90.       sprintf(Temp,"%d 1024 & %d 128 byte packets",Number1K,Number128);
  91.       WriteMsg(Temp);
  92.      }
  93.  else
  94.      {/* empty file */
  95.       Number128 = 0;
  96.       Number1K = 0;
  97.       /*WriteMsg("Empty File");*/
  98.      }
  99.  /* clear comm port ( there may be several NAKs queued up ) */
  100.  SioRxFlush(Port);
  101.  /* get receivers start up NAK, 'C', or 'G' */
  102.  if(!TxStartup(Port,&NCGchar))
  103.    {RestorePSL(Port);
  104.     return(FALSE);
  105.    }
  106.  /* loop over all packets */
  107.  SioDelay(ONE_SECOND/4);
  108.  if(BatchFlag) FirstPacket = 0;
  109.  else FirstPacket = 1;
  110.  Tics = SioTimer();
  111.  for(p=FirstPacket;p<=Number1K+Number128;p++)
  112.        {/* user aborts ? */
  113.         if(SioKeyPress()) if((char)SioKeyRead()==ABORT_CHAR)
  114.           {TxCAN(Port);
  115.            WriteMsg("Aborted by USER");
  116.            RestorePSL(Port);
  117.            return(FALSE);
  118.           }
  119.         /* issue message */
  120.         sprintf(Temp,"Packet %d",p);
  121.         WriteMsg(Temp);
  122.         /* load up Buffer */
  123.         if(p==0)
  124.               {/* Filename packet ! */
  125.                PacketSize = 128;
  126.                k = 0;
  127.                for(i=0;i<strlen(Filename);i++) Buffer[k++] = Filename[i];
  128.                Buffer[k++] = '\0';
  129.                sprintf(Temp,"%ld",FileSize);
  130.                for(i=0;i<strlen(Temp);i++) Buffer[k++] = Temp[i];
  131.                while(k<128) Buffer[k++] = '\0';
  132.               }
  133.         else /* p > 0 */
  134.               {/* DATA Packet: use 1K or 128 byte block ? */
  135.                if(p<=Number1K) PacketSize = 1024;
  136.                else PacketSize = 128;
  137.                /* read next block from disk */
  138.                Code = read(Handle,Buffer,PacketSize);
  139.                if(Code<=0)
  140.                      {SayError(Port,"Error on disk read");
  141.                       RestorePSL(Port);
  142.                       return(FALSE);
  143.                      }
  144.                for(i=Code;i<PacketSize;i++) Buffer[i] = 0x1a;
  145.               }
  146.         /* send this packet */
  147.         if(!TxPacket(Port,p,PacketSize,Buffer,NCGchar))
  148.            {RestorePSL(Port);
  149.             return(FALSE);
  150.            }
  151.         /* must 'restart' after non null packet 0 */
  152.         if(!EmptyFlag&&(p==0)) TxStartup(Port,&NCGchar);
  153.        } /* end -- for(p) */
  154.   WriteCPS(Tics,FileSize,Filename,FALSE);
  155.  /* done if empty packet 0 */
  156.  if(EmptyFlag)
  157.         {WriteMsg("Batch transfer complete");
  158.          RestorePSL(Port);
  159.          return(TRUE);
  160.         }
  161.  /* all done. send EOT up to 10 times */
  162.  close(Handle);
  163.  if(!TxEOT(Port))
  164.      {SayError(Port,"EOT not acknowledged");
  165.       RestorePSL(Port);
  166.       return(FALSE);
  167.      }
  168.  WriteMsg("Transfer Complete");
  169.  RestorePSL(Port);
  170.  return(TRUE);
  171. } /* end -- TxyModem */
  172.  
  173. int RxyModem(
  174.    int Port,          /* COM port [0..3] */
  175.    char *Filename,    /* filename buffer */
  176.    char *Buffer,      /* data buffer */
  177.    char NCGparm,      /* NAK, 'C', or 'G' */
  178.    int BatchFlag)     /* if TRUE, get filename from packet 0 */
  179. {int  i;
  180.  int  Handle;         /* file Handle */
  181.  int  p;              /* packet index */
  182.  int  Code;           /* return code */
  183.  int  FirstPacket;
  184.  char PacketNbr;
  185.  int  PacketSize;     /* 128 or 1024 */
  186.  long FileSize = 0;
  187.  long BytesRX = 0;
  188.  long BytesWanted;
  189.  char Temp[81];
  190.  long Tics;
  191.  int  EOTflag = FALSE;
  192.  char NCGchar;
  193.  /* begin */
  194.  NCGchar = NCGparm;
  195.  Set8N1(Port);
  196.  EOTflag = FALSE;
  197.  WriteMsg("XYMODEM Receive: Waiting for Sender ");
  198.  while(SioKeyPress()) SioKeyRead();
  199.  /* clear comm port */
  200.  SioRxFlush(Port);
  201.  /* Send NAKs, 'C's, or 'G's */
  202.  if(!RxStartup(Port,&NCGchar))
  203.     {RestorePSL(Port);
  204.      return(FALSE);
  205.     }
  206.  /* open file unless BatchFlag is on */
  207.  if(BatchFlag) FirstPacket = 0;
  208.  else
  209.      {/* start with packet 1 */
  210.       FirstPacket = 1;
  211.       /* open file passed in Filename[] for write */
  212.       Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  213.       if(Handle<0)
  214.           {strcpy(Temp,"Cannot open ");
  215.            strcat(Temp,Filename);
  216.            WriteMsg(Temp);
  217.            RestorePSL(Port);
  218.            return(FALSE);
  219.           }
  220.      }
  221.  Tics = SioTimer();
  222.  /* get each packet in turn */
  223.  for(p=FirstPacket;;p++)
  224.      {/* user aborts ? */
  225.       if(SioKeyPress()) if((char)SioKeyRead()==ABORT_CHAR)
  226.         {TxCAN(Port);
  227.          RestorePSL(Port);
  228.          return(FALSE);
  229.         }
  230.       /* issue message */
  231.       sprintf(Temp,"Packet %d",p);
  232.       WriteMsg(Temp);
  233.       /* get next packet */
  234.       if(!RxPacket(Port,p,&PacketSize,Buffer,NCGchar,&EOTflag))
  235.          {RestorePSL(Port);
  236.           return(FALSE);
  237.          }
  238.       if(p==0)
  239.          {/* copy Filename */
  240.           strcpy(Filename,Buffer);
  241.           /* done if null packet 0 */
  242.           if(Filename[0]=='\0')
  243.              {WriteMsg("Batch Transfer Complete");
  244.               RestorePSL(Port);
  245.               return(TRUE);
  246.              }
  247.         }
  248.       BytesRX += (long)PacketSize;
  249.       /* all done if EOT was received */
  250.       if(EOTflag)
  251.          {
  252.           if(FileSize>0L) BytesRX = FileSize;
  253.           WriteCPS(Tics,BytesRX,Filename,FALSE);
  254.           close(Handle);
  255.           WriteMsg("Transfer Complete");
  256.           RestorePSL(Port);
  257.           return(TRUE);
  258.          }
  259.       /* process packet */
  260.       if(p==0)
  261.          {/* open file using filename in packet 0 */
  262.           Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  263.           if(Handle<0)
  264.              {strcat(Buffer," -- open failed");
  265.               WriteMsg(Buffer);
  266.               RestorePSL(Port);
  267.               return(FALSE);
  268.              }
  269.            /* get file length */
  270.            FileSize = atol(&Buffer[1+strlen(Buffer)]);
  271.            BytesWanted = FileSize;
  272.            /* must 'restart' after packet 0 */
  273.            RxStartup(Port,&NCGchar);
  274.           }
  275.       else /* DATA packet */
  276.           {/* write Buffer */
  277.            if(BatchFlag)
  278.               {if(BytesWanted<(long)PacketSize) i = (int) BytesWanted;
  279.                else i = PacketSize;
  280.                i = write(Handle,Buffer,i);
  281.                BytesWanted -= (long)i;
  282.               }
  283.            else write(Handle,Buffer,PacketSize);
  284.           } /* end -- else */
  285.      } /* end -- for(p) */
  286. } /* end - RxyModem */
  287.  
  288. int TxCAN(int Port)
  289. {int i;
  290.  for(i=0;i<6;i++) SioPutc(Port,CAN);
  291.  return(0);
  292. }
  293.  
  294. /* XMODEM send */
  295.  
  296. void XmodemTx(int Port,char *FileName,char *Buffer,int OneKflag)
  297. {if(!FetchName(FileName)) return;
  298.  TxyModem(Port,FileName,Buffer,OneKflag,FALSE);
  299. }
  300.  
  301. /* XMODEM receive */
  302.  
  303. void XmodemRx(int Port,char *FileName,char *Buffer,char NCGchar)
  304. {if(!FetchName(FileName)) return;
  305.  RxyModem(Port,FileName,Buffer,NCGchar,FALSE);
  306. }
  307.  
  308. /* YMODEM send */
  309.  
  310. void YmodemTx(int Port,char *FileSpec,char *Buffer)
  311. {char FileName[15];
  312.  if(!FetchName(FileSpec)) return;
  313.  if(FindFirst(FileSpec,FileName,NULL))
  314.    {TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  315.     while(FindNext(FileName,NULL))
  316.       {SioDelay(1);
  317.        TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  318.       }
  319.    }
  320.  /* send empty filename */
  321.  FileName[0] = '\0';
  322.  SioDelay(1);
  323.  TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  324. }
  325.  
  326. /* YMODEM receive */
  327.  
  328. void YmodemRx(int Port,char *Buffer,char NCGchar)
  329. {char FileName[15];
  330.  do
  331.    {/* receive files till get empty filename */
  332.     RxyModem(Port,FileName,Buffer,NCGchar,TRUE);
  333.     if(SioKeyPress()) return;
  334.    } while(FileName[0]!='\0');
  335. }
  336.